import threading
import time
import dpkt
import pcap
import socket
from netFunctions import *

class NetFrameForwarder(threading.Thread):
    def __init__(self,pc,inbuffer,interface,host1,host2):
        threading.Thread.__init__(self)
        self._interface = interface
        self._packetbuffer = inbuffer
        self._host1 = host1
        self._host2 = host2
        self._running = False
        self._pc = pc
        self._socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
        self._socket.bind((self._interface,0))
        
    def _bufferEmpty(self):
        if self._packetbuffer.length() > 0:
            return False
        else:
            return True
        
    def _getDataFromBuffer(self):
        if self._bufferEmpty():
            return []
        else:
            return self._packetbuffer.getItems(-1)
        
    def _forwardFrame(self,frame,destMac):
        print "[INPUT] ",`frame`
        newframe = dpkt.ethernet.Ethernet()
        newframe.type = frame.type
        newframe.src = frame.src
        #newframe.src = getHwAddr(self._interface)
        newframe.dst = ''+destMac
        newframe.data = frame.data
        print "[OUTPUT] ",`newframe`
        #self._pc.inject(str(newframe),len(str(newframe)))
        self._socket.send(str(newframe))
        
    def _parseFrame(self,frame):
        protocolToForward = [
                             dpkt.ethernet.ETH_TYPE_IP,
                             ]
        l3protoToForward = [
                            dpkt.ip.IP_PROTO_ICMP,
                            ]
        if frame.type in protocolToForward and not isBroadcast(frame.dst):
            packet = frame.data
            if packet.dst != get_ip_address(self._interface,"hex") and isIpUnicast(packet.dst) and packet.p in l3protoToForward:
                if frame.src == self._host1["mac"]:
                    self._forwardFrame(frame, self._host2["mac"])                 
                elif frame.src == self._host2["mac"]:
                    self._forwardFrame(frame, self._host1["mac"])
                
        
    def isRunning(self):
        return self._running
    
    def stop(self):
        self._running = False
        
    def run(self):
        self._running = True
        while self.isRunning():    
            if not self._bufferEmpty():
                frames = self._packetbuffer.getItems(-1)
                for frame in frames:
                    self._parseFrame(frame)            
            time.sleep(0.05)